<template>
	<view class="alvin-select" @click.stop="trigger" :style="[alvinSelectSize]">
		<input type="text" v-model="showText" :placeholder="placeholder" :disabled="!filterable" clearable >
		<view class="alvin-select-suffix" :style="{border: '1px solid rgba（0,0,0,0)'}" :class="[showSuffix]">
			<view class="alvin-select-down-tag">^</view>
		</view>
		<view v-if="showOptions" class="alvin-select-options"
			:style="{'min-width': boundingClientRect.width + 'px', top: optionsGroupTop, margin: optionsGroupMargin}">
			<view v-if="optionsFilter.length !== 0" class="alvin-select-options-item" v-for="item in optionsFilter"
				:key="item.value" @click.stop="select(item)" :class="{active: currentSelect.label === item.label}">
				<text>{{item.label}}</text>
			</view>
			<view v-if="optionsFilter.length === 0" class="alvin-select-options-item text-gray text-xs">暂无数据</view>
		</view>
	</view>
</template>

<script>
	/**
	 * 这是原作者信息，改造控件纯属业务需要，侵删 ，联系微信： alvin198761
	 * 原插件地址 ： https://ext.dcloud.net.cn/plugin?id=2511
	 * easy-select
	 * @author Snoop zhang
	 * @description Select Component
	 * */
	const COMPONENT_NAME = 'alvin-select'
	const MAX_OPTIONS_HEIGHT = 137 // 修改务必也修改easy-select-options的css部分
	const OPTIONS_ITEM_HEIGHT = 33 // 修改务必也修改easy-select-options-item的css部分
	const OPTIONS_MARGIN = 10
	const OPTIONS_PADDING = 6 * 2 + 2 // + 2是border
	const OPTIONS_OTHER_HEIGHT = OPTIONS_MARGIN + OPTIONS_PADDING
	const STORAGE_KEY = '_alvinWindowHeight'
	const SIZE = {
		'medium': {
			width: '240px',
			height: '40px'
		},
		'small': {
			width: '200px',
			height: '30px'
		},
		'mini': {
			width: '160px',
			height: '30px'
		}
	}

	export default {
		name: COMPONENT_NAME,

		model: {
			prop: 'value',
			event: 'input'
		},
		props: {
			filterable: {
				type: Boolean,
				default: false
			},
			windowHeight: {
				type: [Number, String],
				default: 0
			},
			placeholder: {
				type: String,
				default: '请选择'
			},
			value: {
				type: Number,
				default: null
			},
			size: {
				type: String,
				default: 'medium'
			},
			options: {
				type: Array,
				default () {
					return []
				}
			}
		},
		data() {
			return {
				showText: null,
				showOptions: false,
				boundingClientRect: {},
				currentSelect: {},
				optionsGroupTop: 'auto',
				optionsGroupMargin: ''
			}
		},
		computed: {
			showSuffix() {
				return this.showOptions ? 'showOptions' : 'no-showOptions'
			},
			alvinSelectSize() {
				let size = this.size.toLowerCase()
				if (size in SIZE) {
					return {
						width: SIZE[size].width,
						height: SIZE[size].height
					}
				} else {
					return {}
				}
			},
			optionsFilter() {
				if (!this.filterable) {
					return this.options;
				}
				if (!this.showText || this.showText.length === 0) {
					return this.options;
				}
				return this.options.filter(item => {
					return item.label.indexOf(this.showText) != -1;
				})
			}
		},
		mounted() {
			const that = this;  
			const elQuery = uni.createSelectorQuery().in(this)
			elQuery.select('.alvin-select').boundingClientRect(data => {
				this.boundingClientRect = data
			}).exec();
			try {
				if (!this.windowHeight) {
					const storageHeihgt = uni.getStorageSync(STORAGE_KEY)
					if (storageHeihgt) {
						this.alvinWindowHeight = storageHeihgt
						return
					}
					const res = uni.getSystemInfoSync();
					this.alvinWindowHeight = res.windowHeight
					uni.setStorageSync(STORAGE_KEY, this.alvinWindowHeight)
				}
			} catch (e) {
				// error
			}
			//点击其他地方管理 
			document.addEventListener('click',  (e) =>{  
				if (e.target.className != 'alvin-select') {
					that.showOptions = false 
				}
			})
		
	},
	created() {
			this.restore(this.value)
		},
		methods: { 
			trigger(e) {
				const view = uni.createSelectorQuery().in(this)
				view.select('.alvin-select').fields({
					rect: true
				}, data => {
					let {
						top,
						bottom
					} = data
					const thresholdHeight = Math.min(MAX_OPTIONS_HEIGHT + OPTIONS_MARGIN, (this.options
							.length * OPTIONS_ITEM_HEIGHT) +
						OPTIONS_OTHER_HEIGHT)
					bottom = Number(this.windowHeight || this.alvinWindowHeight) - (top + this
						.boundingClientRect.height) // 距离底部的距离等于视口的高度减上top加select组件的高度

					// judge direction
					if (bottom < thresholdHeight) {
						this.optionsGroupDirection = 'up'
						this.optionsGroupTop = -thresholdHeight - 12 + 'px'
						this.optionsGroupMargin = '0'
					} else {
						this.optionsGroupDirection = 'down'
						this.optionsGroupTop = 'auto'
						this.optionsGroupMargin = '10px 0 0 0'
					}

					// 清空原来的组件
					this.showOptions = !this.showOptions;
					if (this.showOptions === true) {
						this.showText = null;
						this.currentSelect = {},
							this.$emit("input", null);
						this.$emit('change', null)
					}
				}).exec();
			},
			select(options) {
				this.showOptions = false
				this.currentSelect = options
				console.log(options);
				this.$emit('change', options)
				this.$emit("input", options.value);
				this.showText = options.label;
			},
			hideOptions() { 
				this.showOptions = false
			},
			//双向绑定，和还原
			restore(value) {
				if (!value) { 
					this.showOptions = false;
					this.currentSelect = null 
					this.$emit('change', null)
					this.$emit("input", null);
					this.showText = null;
					return;
				}
				for (let item in this.options) { 
					if (this.options[item].value === value) {
						this.showText = this.options[item].label
						this.currentSelect = {
							...this.options[item]
						};
						break;
					}
				}
			}
		},
		watch: {
			value(newValue, oldValue) {
				this.restore(newValue);
			}
		},
	}
</script>

<style scoped>
	.alvin-select {
		position: relative;
		border: 1px solid #dcdfe6;
		border-radius: 0px;
		/* font-size: 28rpx; */
		color: #606266;
		outline: none;
		box-sizing: content-box;
		height: 30px;
	}

	.alvin-select input {
		padding: 0 18rpx;
		padding-right: 60rpx;
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		height: 100% !important;
		min-height: 100% !important;
	}

	.alvin-select .alvin-select-suffix {
		position: absolute;
		box-sizing: border-box;
		height: 100%;
		right: 5px;
		top: 0;
		display: flex;
		align-items: center;
		transform: rotate(180deg);
		transition: all .3s;
		transform-origin: center;
	}

	.alvin-select .showOptions {
		transform: rotate(0) !important;
	}

	.alvin-select .no-showOptions {
		transform: rotate(180deg) !important;
	}

	.alvin-select .alvin-select-options {
		position: absolute;
		padding: 6px 0;
		margin-top: 10px;
		border: 1px solid #e4e7ed;
		border-radius: 4px;
		background-color: #fff;
		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
		box-sizing: border-box;
		transform-origin: center top;
		z-index: 2238;
		overflow: scroll;
		max-height: 274rpx;
	}

	.alvin-select .alvin-select-options-item {
		padding: 0 20rpx;
		position: relative;
		white-space: nowrap;
		font-size: 14px;
		color: #606266;
		height: 33px;
		line-height: 33px;
		box-sizing: border-box;
	}

	.alvin-select .active {
		background-color: #F5F7FA
	}
</style>
